/*     */ package com.zimbra.cs.redolog.logger;
/*     */ 
/*     */ import com.zimbra.cs.redolog.RedoLogInput;
/*     */ import com.zimbra.cs.redolog.RedoLogOutput;
/*     */ import com.zimbra.cs.redolog.Version;
/*     */ import java.io.ByteArrayInputStream;
/*     */ import java.io.ByteArrayOutputStream;
/*     */ import java.io.FileDescriptor;
/*     */ import java.io.IOException;
/*     */ import java.io.RandomAccessFile;
/*     */ import java.io.UnsupportedEncodingException;
/*     */ import java.text.SimpleDateFormat;
/*     */ import java.util.Arrays;
/*     */ import java.util.Date;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public class FileHeader
/*     */ {
/*     */   public static final int HEADER_LEN = 512;
/*     */   private static final int SERVER_ID_FIELD_LEN = 127;
/*  70 */   private static final byte[] MAGIC = "ZM_REDO".getBytes();
/*     */   
/*     */   private byte mOpen;
/*     */   
/*     */   private long mFileSize;
/*     */   private long mSeq;
/*     */   private String mServerId;
/*     */   private long mFirstOpTstamp;
/*     */   private long mLastOpTstamp;
/*     */   private long mCreateTime;
/*     */   private Version mVersion;
/*     */   
/*     */   FileHeader()
/*     */   {
/*  84 */     this("unknown");
/*     */   }
/*     */   
/*     */   FileHeader(String serverId) {
/*  88 */     this.mOpen = 0;
/*  89 */     this.mFileSize = 0L;
/*  90 */     this.mSeq = 0L;
/*  91 */     this.mServerId = serverId;
/*  92 */     this.mFirstOpTstamp = 0L;
/*  93 */     this.mLastOpTstamp = 0L;
/*  94 */     this.mCreateTime = 0L;
/*  95 */     this.mVersion = Version.latest();
/*     */   }
/*     */   
/*     */   void write(RandomAccessFile raf) throws IOException
/*     */   {
/* 100 */     if (!this.mVersion.isLatest())
/* 101 */       this.mVersion = Version.latest();
/* 102 */     byte[] buf = serialize();
/* 103 */     raf.seek(0L);
/* 104 */     raf.write(buf);
/* 105 */     raf.getFD().sync();
/*     */   }
/*     */   
/*     */   void read(RandomAccessFile raf) throws IOException {
/* 109 */     raf.seek(0L);
/* 110 */     byte[] header = new byte['Ȁ'];
/* 111 */     int bytesRead = raf.read(header, 0, 512);
/* 112 */     if (bytesRead < 512) {
/* 113 */       throw new IOException("Redolog is smaller than header length of 512 bytes");
/*     */     }
/* 115 */     deserialize(header);
/*     */   }
/*     */   
/*     */   void setOpen(boolean b) {
/* 119 */     if (b) {
/* 120 */       this.mOpen = 1;
/*     */     } else
/* 122 */       this.mOpen = 0;
/*     */   }
/*     */   
/*     */   void setFileSize(long s) {
/* 126 */     this.mFileSize = s;
/*     */   }
/*     */   
/*     */   void setSequence(long seq) {
/* 130 */     this.mSeq = seq;
/*     */   }
/*     */   
/*     */   void setFirstOpTstamp(long t) {
/* 134 */     this.mFirstOpTstamp = t;
/*     */   }
/*     */   
/*     */   void setLastOpTstamp(long t) {
/* 138 */     this.mLastOpTstamp = t;
/*     */   }
/*     */   
/*     */   void setCreateTime(long t) {
/* 142 */     this.mCreateTime = t;
/*     */   }
/*     */   
/*     */   public boolean getOpen() {
/* 146 */     return this.mOpen != 0;
/*     */   }
/*     */   
/*     */   public long getFileSize() {
/* 150 */     return this.mFileSize;
/*     */   }
/*     */   
/*     */   public long getSequence() {
/* 154 */     return this.mSeq;
/*     */   }
/*     */   
/*     */   public String getServerId() {
/* 158 */     return this.mServerId;
/*     */   }
/*     */   
/*     */   public long getFirstOpTstamp() {
/* 162 */     return this.mFirstOpTstamp;
/*     */   }
/*     */   
/*     */   public long getLastOpTstamp() {
/* 166 */     return this.mLastOpTstamp;
/*     */   }
/*     */   
/*     */   public long getCreateTime() {
/* 170 */     return this.mCreateTime;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private byte[] getStringBytes(String str, String charset, int maxlen)
/*     */   {
/* 184 */     String substr = str;
/* 185 */     int len = substr.length();
/* 186 */     while (len > 0) {
/* 187 */       byte[] buf = null;
/*     */       try {
/* 189 */         buf = substr.getBytes(charset);
/*     */       }
/*     */       catch (UnsupportedEncodingException e) {
/*     */         break;
/*     */       }
/* 194 */       if (buf.length <= maxlen)
/* 195 */         return buf;
/* 196 */       substr = substr.substring(0, --len);
/*     */     }
/* 198 */     byte[] buf = new byte[0];
/* 199 */     return buf;
/*     */   }
/*     */   
/*     */   private byte[] serialize() throws IOException
/*     */   {
/* 204 */     ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
/* 205 */     RedoLogOutput out = new RedoLogOutput(baos);
/* 206 */     out.write(MAGIC);
/* 207 */     out.writeByte(this.mOpen);
/* 208 */     out.writeLong(this.mFileSize);
/* 209 */     out.writeLong(this.mSeq);
/*     */     
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 218 */     byte[] serverIdBuf = getStringBytes(this.mServerId, "UTF-8", 127);
/*     */     
/* 220 */     out.writeByte((byte)serverIdBuf.length);
/* 221 */     out.write(serverIdBuf);
/* 222 */     if (serverIdBuf.length < 127) {
/* 223 */       byte[] padding = new byte[127 - serverIdBuf.length];
/* 224 */       Arrays.fill(padding, (byte)0);
/* 225 */       out.write(padding);
/*     */     }
/*     */     
/* 228 */     out.writeLong(this.mFirstOpTstamp);
/* 229 */     out.writeLong(this.mLastOpTstamp);
/* 230 */     this.mVersion.serialize(out);
/* 231 */     out.writeLong(this.mCreateTime);
/*     */     
/* 233 */     int currentLen = baos.size();
/* 234 */     if (currentLen < 512) {
/* 235 */       int paddingLen = 512 - currentLen;
/* 236 */       byte[] b = new byte[paddingLen];
/* 237 */       Arrays.fill(b, (byte)0);
/* 238 */       out.write(b);
/*     */     }
/*     */     
/* 241 */     byte[] headerBuf = baos.toByteArray();
/* 242 */     baos.close();
/* 243 */     if (headerBuf.length != 512) {
/* 244 */       throw new IOException("Wrong redolog header length of " + headerBuf.length + "; should be " + 512);
/*     */     }
/*     */     
/* 247 */     return headerBuf;
/*     */   }
/*     */   
/*     */   private void deserialize(byte[] headerBuf) throws IOException {
/* 251 */     ByteArrayInputStream bais = new ByteArrayInputStream(headerBuf);
/* 252 */     RedoLogInput in = new RedoLogInput(bais);
/*     */     try
/*     */     {
/* 255 */       byte[] magic = new byte[MAGIC.length];
/* 256 */       in.readFully(magic, 0, MAGIC.length);
/* 257 */       if (!Arrays.equals(magic, MAGIC)) {
/* 258 */         throw new IOException("Missing magic bytes in redolog header");
/*     */       }
/* 260 */       this.mOpen = in.readByte();
/* 261 */       this.mFileSize = in.readLong();
/* 262 */       this.mSeq = in.readLong();
/*     */       
/* 264 */       int serverIdLen = in.readByte();
/* 265 */       if (serverIdLen > 127) {
/* 266 */         throw new IOException("ServerId too long (" + serverIdLen + " bytes) in redolog header");
/*     */       }
/* 268 */       byte[] serverIdBuf = new byte[127];
/* 269 */       in.readFully(serverIdBuf, 0, 127);
/* 270 */       this.mServerId = new String(serverIdBuf, 0, serverIdLen, "UTF-8");
/*     */       
/* 272 */       this.mFirstOpTstamp = in.readLong();
/* 273 */       this.mLastOpTstamp = in.readLong();
/* 274 */       this.mVersion.deserialize(in);
/* 275 */       if (this.mVersion.tooHigh()) {
/* 276 */         throw new IOException("Redo log version " + this.mVersion + " is higher than the highest known version " + Version.latest());
/*     */       }
/*     */       
/*     */ 
/*     */ 
/*     */ 
/* 282 */       if (!this.mVersion.atLeast(1, 0)) {
/* 283 */         this.mVersion = new Version(1, 0);
/*     */       }
/* 285 */       this.mCreateTime = in.readLong();
/*     */     } finally {
/* 287 */       bais.close();
/*     */     }
/*     */   }
/*     */   
/* 291 */   private static String DATE_FORMAT = "EEE, yyyy/MM/dd HH:mm:ss.SSS z";
/*     */   
/*     */   public String toString() {
/* 294 */     SimpleDateFormat fmt = new SimpleDateFormat(DATE_FORMAT);
/* 295 */     StringBuilder sb = new StringBuilder(100);
/* 296 */     sb.append("sequence: ").append(this.mSeq).append("\n");
/* 297 */     sb.append("open:     ").append(this.mOpen).append("\n");
/* 298 */     sb.append("filesize: ").append(this.mFileSize).append("\n");
/* 299 */     sb.append("serverId: ").append(this.mServerId).append("\n");
/* 300 */     sb.append("created:  ");
/* 301 */     if (this.mCreateTime != 0L)
/* 302 */       sb.append(fmt.format(new Date(this.mCreateTime))).append(" (").append(this.mCreateTime).append(")");
/* 303 */     sb.append("\n");
/* 304 */     sb.append("first op: ");
/* 305 */     if (this.mFirstOpTstamp != 0L)
/* 306 */       sb.append(fmt.format(new Date(this.mFirstOpTstamp))).append(" (").append(this.mFirstOpTstamp).append(")");
/* 307 */     sb.append("\n");
/* 308 */     sb.append("last op:  ");
/* 309 */     if (this.mLastOpTstamp != 0L) {
/* 310 */       sb.append(fmt.format(new Date(this.mLastOpTstamp))).append(" (").append(this.mLastOpTstamp).append(")");
/* 311 */       if (this.mOpen != 0)
/* 312 */         sb.append(" (not up to date)");
/*     */     }
/* 314 */     sb.append("\n");
/* 315 */     sb.append("version:  ").append(this.mVersion).append("\n");
/* 316 */     return sb.toString();
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/redolog/logger/FileHeader.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */